﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ITAP.ContourBuilder.Components;

using ITAP.ContourBuilder.GUI;
using ITAP.ContourBuilder.Utils;
using ITAP.Core.Modelling;

namespace ITAP.ContourBuilder.Manipulation
{
    public class CommandChangeComponentProperties : SerializedCommand, IContourVisitor
    {
        public CommandChangeComponentProperties(ContourControl control)
            : base(control)
        {
        }

        public override void ObtainPeripheryState(GlobalPeripheryState state)
        {
            base.ObtainPeripheryState(state);
            if (state.MouseState.MouseMode == MouseMode.Down && state.MouseState.State.Clicks == 2)
            {
                ModelPoint point = this.ScreenPointToModelPoint(state.MouseState.State.Location);

                foreach (IContourComponent component in this.control.ContourContainer.SelectedComponentsStack)
                    if (component.CanSelectByPoint(point))
                    {
                        component.AcceptVisitor(this);
                        return;
                    }

                // Если не попали ни по одному элементу, выводим свойства листа
                FormContainerParameters form = new FormContainerParameters();
                form.LeftIndent = this.control.ContourContainer.LeftIndent;
                form.UpIndent = this.control.ContourContainer.UpIndent;
                form.RightIndent = this.control.ContourContainer.RightIndent;
                form.DownIndent = this.control.ContourContainer.DownIndent;

                bool inverted = form.InvertContainer;
                if (form.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    if (form.LeftIndent != this.control.ContourContainer.LeftIndent ||
                        form.UpIndent != this.control.ContourContainer.UpIndent ||
                        form.RightIndent != this.control.ContourContainer.RightIndent ||
                        form.DownIndent != this.control.ContourContainer.DownIndent || form.InvertContainer == true)
                    {
                        this.undoContainer = this.control.ContourContainer.Clone() as ContourContainer;

                        if (form.InvertContainer)
                            this.control.ContourContainer = this.control.ContourContainer.GetInvertContainer();

                        this.control.ContourContainer.LeftIndent = form.LeftIndent;
                        this.control.ContourContainer.UpIndent = form.UpIndent;
                        this.control.ContourContainer.RightIndent = form.RightIndent;
                        this.control.ContourContainer.DownIndent = form.DownIndent;


                        this.control.UpdateModel();
                        this.SaveToHistory();
                    }
                }
            }
        }

        public override string ToString()
        {
            return "Изменение параметров компонента";
        }

        #region IContourVisitor Members

        public void Visit(ITAP.ContourBuilder.Components.ContourModel model)
        {
            throw new NotImplementedException();
        }

        public void Visit(ITAP.ContourBuilder.Components.ContourContainer container)
        {
            throw new NotImplementedException();
        }

        public void Visit(ITAP.ContourBuilder.Components.ContourElement element)
        {
            FormElementProperties form = new FormElementProperties();
            ContourContainer container = element.GetRootContainer();
            form.Height = element.Height;
            form.StartPoint = container.AbsoluteToInner(element.StartPoint);
            form.EndPoint = container.AbsoluteToInner(element.EndPoint);
            form.OffsetValue = element.Offset;


            if (form.ShowDialog() == System.Windows.Forms.DialogResult.OK &&
                (form.Height != element.Height ||
                !container.InnerToAbsolute(form.StartPoint).Equals(element.StartPoint) ||
                container.InnerToAbsolute(form.EndPoint).Equals(element.EndPoint)) || form.OffsetValue != element.Offset)
            {
                ModelPoint startPoint = container.InnerToAbsolute(form.StartPoint);
                ModelPoint endPoint = container.InnerToAbsolute(form.EndPoint);

                this.undoContainer = this.control.ContourContainer.Clone() as ContourContainer;

                element.Offset = form.OffsetValue;

                if (element.StartConnectedComponent != null)
                    element.StartConnectedComponent.MoveTo(startPoint);
                else
                    element.MoveStartPoint(startPoint);

                if (element.EndConnectedComponent != null)
                    element.EndConnectedComponent.MoveTo(endPoint);
                else
                    element.MoveEndPoint(endPoint);

                element.Height = form.Height;

                this.control.UpdateModel();
                this.SaveToHistory();
            }

        }

        public void Visit(ITAP.ContourBuilder.Components.ContourConnector connector)
        {
            FormConnectorProperties form = new FormConnectorProperties();
            ContourContainer container = connector.GetRootContainer();
            form.ConnectorPosition = container.AbsoluteToInner(connector.Position);
            if (form.ShowDialog() == System.Windows.Forms.DialogResult.OK &&
                !container.InnerToAbsolute(form.ConnectorPosition).Equals(connector.Position))
            {
                this.undoContainer = this.control.ContourContainer.Clone() as ContourContainer;
                ModelPoint point = container.InnerToAbsolute(form.ConnectorPosition);
                connector.MoveTo(point);
                this.control.UpdateModel();
                this.SaveToHistory();
            }
        }

        public void Visit(ITAP.ContourBuilder.Components.ContourElementHook hook)
        {
            throw new NotImplementedException();
        }

        public void Visit(ITAP.ContourBuilder.Components.ContourText text)
        {

        }

        public void Visit(ITAP.ContourBuilder.Components.ContourCommentLine commentLine)
        {

        }

        public void Visit(ITAP.ContourBuilder.Components.Dimensions.Dimension dimension)
        {
            FormDimensionProperties form = new FormDimensionProperties();
            form.ChangeTextDirection = dimension.ChangeTextDirection;
            form.Prefix = dimension.PrefixSymbol;
            if (form.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                if (form.ChangeTextDirection != dimension.ChangeTextDirection ||
                dimension.PrefixSymbol != form.Prefix)
                {
                    this.undoContainer = this.control.ContourContainer.Clone() as ContourContainer;
                    dimension.ChangeTextDirection = form.ChangeTextDirection;
                    dimension.PrefixSymbol = form.Prefix;
                    this.control.UpdateModel();
                    this.SaveToHistory();
                }
            }
        }

        FormHoleProperties form = null;
        public void Visit(ITAP.ContourBuilder.Components.ContourHole hole)
        {
            form = new FormHoleProperties();
            form.Radius = hole.Radius;
            form.HolePosition = this.control.ContourContainer.AbsoluteToInner(hole.Position);

            if (form.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                if (form.Radius != hole.Radius ||
                    !this.control.ContourContainer.InnerToAbsolute(form.HolePosition).Equals(hole.Position))
                {
                    this.undoContainer = this.control.ContourContainer.Clone() as ContourContainer;
                    ModelPoint point = this.control.ContourContainer.InnerToAbsolute(form.HolePosition);
                    hole.Radius = form.Radius;
                    hole.MoveTo(point);
                    this.control.UpdateModel();
                    this.SaveToHistory();
                }
            }
        }

        #endregion
    }
}
